#include <gtk/gtk.h>
#include <stdio.h>

#include "gtkutils.h"

#include "fileutils.h"
#include "stringutils.h"
#include "etc/network/networkconfig.h"
#include "cjsonutils.h"

void sayHello() {
    printf("hello word\n");
}

static const char *path;

GtkTextBuffer *text_buffer;
GtkTextView *text_view;
GtkComboBox *combo_iface;
GtkEntry *file_entry;

GSList *ifaces;
GtkListStore *ifaces_list_store;
GtkCellRendererText *renderText;

enum {
    NETWORK_IFACE,
};

createGAsyncReadyCallbackSourceObjectFunc(paste_receiver, GdkClipboard, GtkEntry) {
    GError *error = NULL;

    char * text = clipboardReadTextFinish(source_object, result, &error);
    if (text) {
        entrySetText(user_data, text);
    }
}

createSignalObjectFunc(paste_config_path, GtkEntry) {
    GdkClipboard *clipboard = createClipboardWithWidget(user_data);
    clipboardReadTextAsync(clipboard, NULL, paste_receiver,user_data);
}

createCellLayoutDataFunc(render_combo_text) {

}

static void update_combo_list() {
    listStoreClear(ifaces_list_store);

    GtkTreeIter treeIter = {0};
    for (GSList *iter = ifaces; iter; iter = iter->next) {
        listStoreAppend(ifaces_list_store, &treeIter);
        listStoreSet(ifaces_list_store, &treeIter, NETWORK_IFACE, iter->data, -1);
    }
    setComboBoxActive(combo_iface, 0);
}

createSignalObjectFunc(read_tobuffer, GtkEntry) {
    path = entryGetText(user_data);
    if (path) {
        char buffer[10000] = {0};
        if (FileReadToBuffer(path, buffer, sizeof(buffer))) {
            textBufferSetText(text_buffer, buffer, -1);
            GS_FREE_ALL_CLEAN(ifaces);
            NetworkConfigInterfaceNames(path, &ifaces);
            update_combo_list();
        }
    }
}

createSignalObjectFunc(build_ifaces, GtkComboBox) {
    GtkTreeIter iter = {0};
    char *str;
    if (gtk_combo_box_get_active_iter(combo_iface, &iter)) {
        
        treeModelGet(convTreeModel(ifaces_list_store), &iter, NETWORK_IFACE, &str, -1);

        ConfigInterface interface = {0};
        if (NetworkConfigInterface(path, str, &interface)&& NetworkConfigInterfaceSectionProperties(path, str, &interface.properties)) {
            GSList *props = NULL;
            for (GSList *iter = interface.properties; iter; iter = iter->next) {
                char buffer[1000] = {0};
                S_CLEARN(buffer);
                char keybuffer[100] = {0};
                createFormat(keybuffer, '-', 30-strlen(((ConfigInterfaceProperty*)iter->data)->key));
                sprintf(buffer, "%s %s> %s", ((ConfigInterfaceProperty*)iter->data)->key, keybuffer, ((ConfigInterfaceProperty*)iter->data)->value);
                props = g_slist_append(props, createBufferCopy(buffer));
            }

            char properties[10000] = {0};
            if (splitToStringWithSeparator(props, "\n", properties)) {
                textBufferSetText(text_buffer, properties, -1);
            }
            GS_FREE_ALL_CLEAN(props);
        }
    }
}

createSignalObjectFunc(build_ifaces_json, GtkComboBox) {
    GtkTreeIter iter = {0};
    char *str;
    if (gtk_combo_box_get_active_iter(combo_iface, &iter)) {
        treeModelGet(convTreeModel(ifaces_list_store), &iter, NETWORK_IFACE, &str, -1);

        ConfigInterface interface = {0};
        if (NetworkConfigInterface(path, str, &interface)&& NetworkConfigInterfaceSectionProperties(path, str, &interface.properties)) {

            cJson iface = createJsonObject();
            addStringToObject(iface, "interface", interface.iface);
            addStringToObject(iface, "isauto", interface.isAuto?"yes":"no");
            addStringToObject(iface, "type", interface.ipType);
            addStringToObject(iface, "work", interface.workType);
            if (interface.properties != NULL) {
                cJson props = addObjectToObject(iface, "properties");
                for (GSList *iter2 = interface.properties; iter2; iter2 = iter2->next) {
                    ConfigInterfaceProperty *propertey = (ConfigInterfaceProperty*)iter2->data;
                    addStringToObject(props, propertey->key, propertey->value);
                }
            }
            GS_FREE_ALL_CLEAN(interface.properties);

            char *json = toStringJson(iface);
            if (json) {
                textBufferSetText(text_buffer,json, -1);
                free(json);
            }

            deleteJsonObject(iface);
        }
    }
}

createSignalObjectFunc(delete_iface, GtkEntry) {
    GtkTreeIter iter = {0};
    char *str;
    if (gtk_combo_box_get_active_iter(combo_iface, &iter)) {
        gtk_tree_model_get(convTreeModel(ifaces_list_store), &iter, NETWORK_IFACE, &str, -1);
        NetworkConfigRemoveConfigInterface(path, str);

        read_tobuffer(widget, user_data);
    }
}

static void activate(GtkApplication *app, gpointer user_data) {
    GtkWindow *window;
    window = createWindowWithTitleSize(app, "gtk-network-config", 600, 300);
    file_entry = createEntry();
    ifaces_list_store = createListStore(1, G_TYPE_STRING);
    renderText = createCellRendererText();
    combo_iface = createComboBoxWithModel(GTK_TREE_MODEL(ifaces_list_store));
    setCellLayout(combo_iface, renderText, "text", NETWORK_IFACE, render_combo_text, false);

    text_buffer  = createTextBuffer(NULL);
    text_view = createTextViewWithTextBuffer(text_buffer);
    setWidgetVerticalExpand(text_view, true);

    GtkBox *input_ctl = createBoxWithHorizntalAppends(5, 
        createLabel("配置文件路径："), 
        file_entry, 
        createButtonAction(file_entry, "粘贴路径", paste_config_path),
        createButtonAction(file_entry, "读取配置", read_tobuffer),
        NULL
    );
    setWidgetHorizntalExpand(input_ctl, true);
    setWidgetHorizntalAlign(input_ctl, ACENTER);

    GtkBox *iface_ctl = createBoxWithHorizntalAppends(5, 
        createLabel("接口操作:"),
        combo_iface,
        createButtonAction(text_buffer, "构建属性列表", build_ifaces),
        createButtonAction(combo_iface, "构建json信息", build_ifaces_json),
        createButtonAction(file_entry, "删除接口", delete_iface),
        NULL
    );
    setWidgetHorizntalExpand(iface_ctl, true);
    setWidgetHorizntalAlign(iface_ctl, ACENTER);

    GtkBox *mainBox = createBoxWithVerticalAppends(5,
        input_ctl,
        iface_ctl,
        text_view,
        NULL
    );
    setBoxFullMargin(mainBox, 10);

    setWindowChild(window, mainBox);
    showWindow(window);
}

int	main(int argc, char **argv) {

    GtkApplication *app;
    int status;

    app = createApplicationConnectActivate("gtk.example.template", 
                                G_APPLICATION_FLAGS_NONE, activate);

    status = runApplication(app, argc, argv);
    objectUnref(app);

    return status;
}

